﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Jhong.FunMVC
{
    using Microsoft.Owin;
    using Microsoft.Owin.Helpers;
    using System.IO;

    public class Request : IDisposable
    {
        private IOwinRequest _owinRequest;

        private RouteBase _routeBase;

        public Request(IOwinRequest owinRequest, RouteBase routeBase)
        {
            this._routeBase = routeBase;
            this._owinRequest = owinRequest;
        }

        private void FillPost()
        {
            if (false == string.IsNullOrWhiteSpace(this.ContentType) && this.ContentType.IndexOf("multipart/form-data", StringComparison.OrdinalIgnoreCase) >= 0) MuilPartPostCollection.Fill(this);
            else DefaultPostCollection.Fill(this);
        }


        


        public IDictionary<string, object> Envirment
        {
            get
            {
                return this._owinRequest.Environment;
            }
        }

        public string UserHostAddress
        {
            get
            {
                return this._owinRequest.Get<string>("server.RemoteIpAddress");
            }
        }

        public string Method
        {
            get
            {
                return this._owinRequest.Method.ToUpper();
            }
        }

        public Uri Uri
        {
            get
            {
                return this._owinRequest.Uri;
            }
        }

        private QueryString _queryString;

        public QueryString QueryString
        {
            get
            {
                if (null == this._queryString) this._queryString = new QueryString(this._owinRequest.QueryString);
                return this._queryString;
            }
        }

        public Stream BodyStream
        {
            get
            {
                return this._owinRequest.Body;
            }
        }

        public RequestCookieCollection Cookie
        {
            get
            {
                return this._owinRequest.Cookies;
            }
        }

        public int ContentLength
        {
            get
            {
                return int.Parse(this._owinRequest.Headers["Content-Length"]);
            }
        }

        public string ContentType
        {
            get
            {
                return this._owinRequest.ContentType;
            }
        }

        public IHeaderDictionary Headers
        {
            get
            {
                return this._owinRequest.Headers;
            }
        }

        public HostString Host
        {
            get
            {
                return this._owinRequest.Host;
            }
        }



        public string RemoteIpAddress
        {
            get
            {
                return this._owinRequest.RemoteIpAddress;
            }
        }

        public int? RemotePort
        {
            get
            {
                return this._owinRequest.RemotePort;
            }
        }

        public string Scheme
        {
            get
            {
                return this._owinRequest.Scheme;
            }
        }

        public string Accept
        {
            get
            {
                return this._owinRequest.Accept;
            }
        }

        private string _controller;
        public string Controller
        {
            get
            {
                if (null == this._controller)
                {
                    var paths = this.Uri.AbsolutePath.Split('/');
                    this._controller = paths.Count() >= 2 ? paths[1] : "Home";
                }
                return this._controller;
            }
            internal set
            {
                this._controller = value;
            }
        }

        private string _action;
        public string Action
        {
            get
            {
                if (null == this._action)
                {
                    var paths = this.Uri.AbsolutePath.Split('/');
                    this._action = paths.Count() >= 3 ? paths[2] : "Index";
                }
                return _action;
            }
            internal set
            {
                this._action = value;
            }
        }

        private Forms _forms;
        public Forms Forms
        {
            get
            {
                if (null != this._forms) return this._forms;
                this._forms = new Forms();
                if (this.Method.IndexOf("GET") < 0) FillPost();
                return this._forms;
            }
        }

        public string this[string key]
        {
            get
            {
                if (null != this.Forms.FormCollection && null != this.Forms.FormCollection[key]) return this.Forms.FormCollection[key];
                if (null != this.QueryString[key]) return this.QueryString[key];
                return null;
            }
        }


        public void Dispose()
        {
            this.BodyStream.Dispose();
        }
    }

    public class Forms
    {
        public IFormCollection FormCollection { get; internal set; }

        private HttpFileCollection _files;
        public HttpFileCollection Files
        {
            get
            {
                if (null != this._files) return this._files;
                this._files = new HttpFileCollection();
                return this._files;
            }
        }
    }
}
